题目&wp链接:
https://github.com/eboda/35c3/tree/master/post
35C3-POST
hint: flag is in db
Hint2: the lovely XSS is part of the beautiful design and insignificant for the challenge
Hint3: You probably want to get the source code, luckily for you it’s rather hard to configure nginx correctly.
功能点很简单,注册,登录,上传文件,评论。
测试了< >
被实体编码,上传php文件不解析。
提示xss无用,nginx配置有问题,在Vulhub中提到了常见的nginx配置问题。
结合提示中的源码泄露,这里尝试nginx的alias配置不当导致目录穿越漏洞。
整个过程就一个uploads
目录,构造payload:https://50.3.232.201:8000/uploads../
得到一个default.backup:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45server {
listen 80;
access_log /var/log/nginx/example.log;
server_name localhost;
root /var/www/html;
location /uploads {
autoindex on;
alias /var/www/uploads/;
}
location / {
alias /var/www/html/;
index index.php;
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.2-fpm.sock;
}
}
location /inc/ {
deny all; # 禁止直接访问
}
}
server {
listen 127.0.0.1:8080;
access_log /var/log/nginx/proxy.log;
if ( $request_method !~ ^(GET)$ ) {
return 405;
}
root /var/www/miniProxy;
location / {
index index.php;
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.2-fpm.sock;
}
}
}
说明8080端口还有另一个服务,即在/var/www/miniProxy
目录下,直接访问https://50.3.232.201:8000/uploads../miniProxy/
可以直接下载php源码,不会解析,这个页面的功能大概就是web的proxy。
此外,通过目录穿越可以下载到全部php源码。
源码基本浏览了一遍,加上提示,我们要拿到数据库里面的flag,在db.php
的38行出中有一处反序列化操作unserialize()
:
而该函数的功能是将从数据库取出的数据进行反序列化操作,db.php
的52行:
所以我们要想控制这个unserialize()
函数,就得先往数据库里面插入我们的数据,55行:
全局搜索insert
操作,共两处,一处注册,一处提交post数据。
post.php的41行:
全局搜索save()
函数,在default.php的19行:
save()
函数中insert()
,在db.php中的55行
再跟进DB::prepare_params()
,db.php的18行:
这里中途对array_map()
没理解好,卡了很久:https://php.net/manual/en/function.array-map.php
到这里,我们要传入一个$serializedobject$
开头的字符串,才能使得查库操作时触发我们的unserialize()
,但insert的时候过滤了这个字符串前缀,在官方的wp中提到,我们可以使用全角符号的unicode字符,mssql会自动转换,以$
符号存入数据库中。
这里0xEF 0xBC 0x84
会被mssql存储为$
下面构造反序列化的攻击链:
首先default.php
73行
调用了post.php的63行,使用了query函数查询
同时在post.php
中的Attachment类
控制$za
属性传入soapClient类,使之在上图19行调用了open()
方法,因为不存在,所以触发soapClient的__call
方法(这里猜想有soap服务,另一个8080端口的服务暗示我们了ssrf,加上这里unserialize的利用功能点少)
payload:
$
用brup的hex修改
8080端口服务只允许get型数据,但是从其服务中来看我们要用post型去打内网数据库,所以这里就利用soapclient的clrf发起get请求,gopher模拟post